import json
import re

from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from apps.carts.utiles import merge_cart_cookie_to_redis
from apps.users.models import Users, Address

# 加密
from apps.users.utils import generate_verify_token, check_verify_token

# 用户名判断
from utils.viewmixin import LoginMixin


class UsernameCountView(View):

    def get(self, requests, username):
        count = Users.objects.filter(username=username).count()

        return JsonResponse({"count": count, "code": 0, "errmsg": 'ok'})


# 注册
class RegisterView(View):

    def post(self, requests):
        # 获取数据
        body_dict = json.loads(requests.body)

        username = body_dict.get("username")
        password = body_dict.get("password")
        password2 = body_dict.get("password2")
        mobile = body_dict.get("mobile")
        sms_code = body_dict.get("sms_code")
        allow = body_dict.get("allow")

        # 验证数据

        # todo 验证 手机验证码
        # 获取redis 手机验证码
        redis_cli = get_redis_connection("code")

        redis_mobile_sms = redis_cli.get("sms_%s" % mobile)

        if redis_mobile_sms is None:
            return JsonResponse({"code": 400, "message": "短信验证码过期"})

        if redis_mobile_sms.decode() != sms_code:
            return JsonResponse({"code": 400, "message": "短信验证码错误"})

        # 验证是否为空
        # all 里传入列表 如果列表里 任一元素为flase或者空 结果就是false
        if not all([username, password, password2, mobile, sms_code, allow]):
            return JsonResponse({"code": "400", "errmsg": "register fail"})
        # 3.2正则验证
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return JsonResponse({"code": "400", "errmsg": "register fail"})
        # 保存数据

        # user = Users(username=username, password=password, mobile=mobile)

        # user.set_password(password)
        user = Users.objects.create_user(username=username, password=password, mobile=mobile)

        # 状态保存
        login(requests, user)

        response = JsonResponse({"code": "0", "errmsg": "ok"})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 5)

        # user.save()
        # 返回数据

        return response


# 登陆
class LoginView(View):
    def post(self, request):
        # 1 接受数据 json
        body = request.body
        data_dict = json.loads(body)
        username = data_dict.get("username")
        password = data_dict.get("password")
        remembered = data_dict.get("remembered")

        # 2 验证数据 是否为空
        if not all([username, password]):
            return JsonResponse({"code": "400", "errmsg": "参数不全"})

        if re.match('1[3-9]\d{9}', username):
            Users.USERNAME_FIELD = "mobile"
        else:
            Users.USERNAME_FIELD = 'username'

        # 3 验证用户名和密码是否正确
        # 如果用户名密码正确 返回User对象 否则返回None

        user = authenticate(username=username, password=password)

        if user is None:
            return JsonResponse({"code": "400", "errmsg": "用户名或者密码错误"})

        # 4 状态保持  session
        login(request, user)

        # 5 判断是否记住登录 设置session的有效期
        if remembered:
            # 记住登录 默认2周
            request.session.set_expiry(None)

        else:
            # 不记住登录  浏览器关闭 session过期
            request.session.set_expiry(0)

        response = JsonResponse({"code": "0", "errmsg": "ok"})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 5)
        # 6 返回响应

        # 合并购物车

        response = merge_cart_cookie_to_redis(request, user, response)

        return response


class LogoutView(View):

    def delete(self, requests):
        # todo 清除用户数据 cookie

        """实现退出登录逻辑"""
        # 清理session
        logout(requests)
        # 退出登录，重定向到登录页

        requests.session.clear()

        response = JsonResponse({"code": "0", "errmsg": "ok"})

        response.delete_cookie("username")
        # 6 返回响应
        return response


class UserInfoView(LoginRequiredMixin, View):

    def get(self, request):
        info_data = {
            "username": request.user.username,
            "mobile": request.user.mobile,
            "email": request.user.email,
            "email_active": request.user.email_active
        }

        return JsonResponse({
            'code': 0,
            'errmsg': '个人中心',
            "info_data": info_data
        })


# 添加邮箱
class SaveEmail(LoginMixin, View):
    def put(self, requests):
        json_data = requests.body

        json_dict = json.loads(json_data)

        email = json_dict.get("email")

        if not email:
            return JsonResponse({"code": "400", "errmsg": "邮箱地址不能为空"})

        if not re.match(r'^[a-z0-9][\w\\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return JsonResponse({"code": 400, "message": '邮箱错误'})
        try:
            requests.user.email = email
            requests.user.save()
        except Exception as e:
            print(e)
            return JsonResponse({"code": "400", "errmsg": "邮箱保存失败"})

        # todo 发送邮件
        # 异步发送验证邮件
        from celery_tasks.email.tasks import send_verify_email

        verify_url = 'http://www.meiduo.site:8080/success_verify_email.html?%s' % generate_verify_token(
            requests.user.id)

        send_verify_email.delay(email, verify_url)

        return JsonResponse({"code": 0, "message": "ok"})


class EmailVerifView(View):

    def put(self, requests, token_id):

        # token_id = requests.GET.get("token_id")
        # 解密
        user_id = check_verify_token(token_id)
        print(user_id)
        try:
            user = Users.objects.get(id=user_id)

            user.email_active = True

            user.save()
        except Exception as e:
            print(e)
            print("邮箱验证失败")

        return JsonResponse({"code": '0', "message": "邮箱认证成功"})


class AddAddress(LoginMixin, View):

    def post(self, requests):
        body_json = requests.body

        json_dict = json.loads(body_json)

        user = requests.user

        city_id = json_dict.get("city_id")
        district_id = json_dict.get("district_id")
        email = json_dict.get("email")
        mobile = json_dict.get("mobile")
        place = json_dict.get("place")
        province_id = json_dict.get("province_id")
        receiver = json_dict.get("receiver")
        tel = json_dict.get("tel")
        title = json_dict.get("title")

        # 数据验证
        if not all([city_id, district_id, mobile, place, province_id, receiver, title]):
            return JsonResponse({"code": 400, "errmsg": "信息不全"})

        try:
            # 保存数据库
            address = Address(user=user,
                              title=title,
                              receiver=receiver,
                              province_id=province_id,
                              city_id=city_id,
                              district_id=district_id,
                              place=place,
                              mobile=mobile,
                              tel=tel,
                              email=email)

            address.save()
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "数据库异常"})

        ret = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email

        }
        return JsonResponse({"code": 400, "errmsg": "保存成功", "address": ret})


# 显示地址
class ShowAddress(LoginMixin, View):

    def get(self, request):
        #
        user = request.user

        addresses = Address.objects.filter(user=user, is_deleted=False)

        # 创建空的列表
        address_dict_list = []
        # 遍历
        for address in addresses:
            address_dict = {
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "city": address.city.name,
                "district": address.district.name,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            }

            address_dict_list.append(address_dict)
            # 将默认地址移动到最前面
        #     default_address = request.user.default_address
        #     print(default_address)
        #     if default_address.id == address.id:
        #         # 查询集 addresses 没有 insert 方法
        #         address_dict_list.insert(0, address_dict)
        #     else:
        #         address_dict_list.append(address_dict)
        #
        # default_id = request.user.default_address_id

        # return JsonResponse({'code': 0,
        #                      'errmsg': 'ok',
        #                      'addresses': address_dict_list,
        #                      'default_address_id': default_id})

        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'addresses': address_dict_list})


class UpdateTitle(LoginMixin, View):

    def put(self, requests, addr_id):
        new_title = json.loads(requests.body).get("title")

        try:
            addr = Address.objects.get(id=addr_id)

            addr.title = new_title

            addr.save()
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "数据库异常"})

        return JsonResponse({"code": 0, "errmsg": "ok"})


class DelANDUpdateAddr(LoginMixin, View):

    def delete(self, requests, addr_id):

        try:
            addr = Address.objects.get(id=addr_id)

            addr.is_deleted = True

            addr.save()
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "数据库异常"})

        return JsonResponse({"code": 0, "errmsg": "ok"})

    def put(self, requests, addr_id):

        body_json = requests.body

        json_dict = json.loads(body_json)

        # user = requests.user

        city_id = json_dict.get("city_id")
        district_id = json_dict.get("district_id")
        email = json_dict.get("email")
        mobile = json_dict.get("mobile")
        place = json_dict.get("place")
        province_id = json_dict.get("province_id")
        receiver = json_dict.get("receiver")
        tel = json_dict.get("tel")
        title = json_dict.get("title")

        # 数据验证
        if not all([city_id, district_id, mobile, place, province_id, receiver, title]):
            return JsonResponse({"code": 400, "errmsg": "信息不全"})

        try:
            addr = Address.objects.get(id=addr_id)

            # 保存数据库
            # addr.user = user,
            addr.title = title
            addr.receiver = receiver
            addr.province_id = province_id
            addr.city_id = city_id
            addr.district_id = district_id
            addr.place = place
            addr.mobile = mobile
            addr.tel = tel
            addr.email = email

            addr.save()

        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "数据库异常"})

        ret = {
            "id": addr.id,
            "title": addr.title,
            "receiver": addr.receiver,
            "province": addr.province.name,
            "city": addr.city.name,
            "district": addr.district.name,
            "place": addr.place,
            "mobile": addr.mobile,
            "tel": addr.tel,
            "email": addr.email

        }
        return JsonResponse({"code": 400, "errmsg": "保存成功", "address": ret})


class UpdatePwd(LoginMixin, View):

    def put(self, request):
        json_data = request.body

        json_dict = json.loads(json_data)

        new_password = json_dict.get("new_password")
        old_password = json_dict.get("old_password")

        if not all([new_password, old_password]):
            return JsonResponse({"code": 400, "errmsg": "数据xxx"})

        try:
            # 判断用户名密码对不对
            user = authenticate(username=request.user.username, password=old_password)

            if not user:
                return JsonResponse({"code": 400, "errmsg": "原密码错误"})

            user.set_password(new_password)

            user.save()
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "数据库异常"})

        # 退出操作

        """实现退出登录逻辑"""
        # 清理session
        logout(request)
        # 退出登录，重定向到登录页

        request.session.clear()

        response = JsonResponse({"code": "0", "errmsg": "ok"})

        response.delete_cookie("username")

        return response
